#ifndef prs_FrmDouble_H
#define prs_FrmDouble_H

#include "prs_FrmControl.h"
#include "prs_FrmUseTemplate.h"
#include "prs_FrmDoubleStyle.h"
#include "frm_control_TDouble.h"

namespace prs {

///////////////////////////////////////////////////////////////////////////////            
struct TNodeFrmDouble;
///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmDoubleControl : public frm::control::TDouble
{
  TNodeFrmDoubleControl(
    frm::control::TWindow &Window,
    TNodeFrmDouble &Node
  ):TDouble(Window),node(Node) {}
  //
  virtual bool UpdateValue(svl::TString V);
  
private:  
  TNodeFrmDouble &node;
};

///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmDouble : public TNodeFrmControl
{
  DECLARE_ClientNode()
  //
  typedef TNodeFrmDoubleStyle   TStyle;
  typedef TNodeFrmDoubleControl TControl;
  //
  TAttrNodeType<nodeType_Double> NodeType;
  TAttrBindPropDouble<attrName_Value,TNodeUseTemplateParam*> Value;
  TAttrBindPropInteger<attrName_Precision,TNodeUseTemplateParam*> Precision;
  TAttrBool<attrName_EnEdit> EnEdit;
  TAttrPointerNoCopy<attrName_Control,TNodeFrmDoubleControl*> Control;
  //
  TNodeFrmDouble():NodeType(this),Value(this),Precision(this),Control(this),EnEdit(this) { precision = 6; }
 ~TNodeFrmDouble() { delete Control.GetValue(); }
  
 TNodeFrmDoubleControl *BuildControl(
    frm::control::TPanel *ParentControl
  );
  
private:
  virtual void   TNode_SetPropDoubleValue(TAttrDoubleBase &Attr,double V);
  virtual double TNode_GetPropDoubleValue(TAttrDoubleBase &Attr);
  virtual void   TNode_SetPropIntegerValue(TAttrIntegerBase &Attr,int P);
  virtual int    TNode_GetPropIntegerValue(TAttrIntegerBase &Attr);
  void updateValueInControl();
  
  double value;
  int precision;
  svl::TLocksStack::TState St;
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TRuleFrmDouble : public snt::TRule, public TFrmDict
{
  TRuleFrmDouble(
    snt::text::TContext &Context,
    svl::TVariant &VParentNode,
    TRuleFrmChildrenBase &RFrmChildren,
    TRuleSetNodeIdOptionally &RSetNodeIdOptionally,
    TRuleSetAttrValue &RSetAttrValue,
    TRuleSetStyle &RStyle
  );

private:  
  bool FSetParamDouble(TRuleSetAttrValue::TFuncValueIdentParams &Params) {
    return TNodeDefTemplate::AddLinkAttrByParamId(Params.Attr,TFrmDoubleValue(),Params.Ident,Params.OutError);
  }
  bool FSetParamPrecision(TRuleSetAttrValue::TFuncValueIdentParams &Params) {
    return TNodeDefTemplate::AddLinkAttrByParamId(Params.Attr,TFrmIntegerValue(),Params.Ident,Params.OutError);
  }
  bool FSetParamBool(TRuleSetAttrValue::TFuncValueIdentParams &Params) {
    return TNodeDefTemplate::AddLinkAttrByParamId(Params.Attr,TFrmBoolValue(),Params.Ident,Params.OutError);
  }
  //
  svl::TVariant &vParentNode;
  snt::TAlter AAttr1;
  snt::TRule  RAttr1,RAttr;
  //
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////
}

#endif
